from interface.widget import Page, PagePort, scale, scale_factor, CommonAdapter, YScrollableContainer
from tkinter import ttk
from interface.pages.chat import ChatPage
from utils import memory
from utils.network import request, RespondError
import traceback
import threading
import time


class UserList(YScrollableContainer):
    def __init__(self, master):
        YScrollableContainer.__init__(self, master)


class ReceiveAgent(threading.Thread):

    def __init__(self):
        threading.Thread.__init__(self)
        self.daemon = True
        self._continue = True

    def update_users(self):
        res = request('/user/all', {})
        for user in res['list']:
            if user['account'] not in memory.users:
                memory.users[user['account']] = {
                    'account': user['account'],
                    'username': user['username'],
                    'messages': []
                }

    def update_messages(self):
        res = request('/message/recv', {})
        self.update_users()
        for message in res['messages']:
            memory.add_message(message)

    def run(self):
        while self._continue:
            try:
                self.update_messages()
            except Exception as e:
                traceback.print_exception(e)
            time.sleep(0.5)

    def stop(self):
        self._continue = False


class MainPage(Page):

    def __init__(self, master):
        Page.__init__(self, master)
        self.receive_agent = None
        self.user_label = None
        self.chat_page_port = None
        self.user_list = None
        self.user_count = 0
        self.start_receive_agent()
        self.displayed_users = []
        self.thread_continue = True

    def content(self, master):
        body = ttk.Frame(master)
        body.place(**scale(relx=0, rely=0, relwidth=1, relheight=1, height=-30))

        user_list = UserList(body)
        user_list.relx = 0
        user_list.rely = 0
        user_list.relwidth = 0.3
        user_list.relheight = 1
        user_list.display()
        self.user_list = user_list

        chat_page_port = PagePort(body)
        chat_page_port.relx = 0.3
        chat_page_port.rely = 0
        chat_page_port.relwidth = 0.7
        chat_page_port.relheight = 1
        chat_page_port.display()

        ttk.Style().configure('MainPage.Foot.TFrame', background='#cccccc')
        foot = ttk.Frame(master, style='MainPage.Foot.TFrame')
        foot.place(**scale(relx=0, rely=1, y=-30, relwidth=1, height=30))

        ttk.Style().configure('MainPage.Foot.TLabel', background='#cccccc')
        user_label = ttk.Label(foot, style='MainPage.Foot.TLabel',
                               text='当前用户：{} ({})'.format(None, None))
        user_label.place(**scale(x=20, y=0, relheight=1))
        self.user_label = user_label

        self.chat_page_port = chat_page_port

        def open_multi_send_page():
            from interface.pages.multi_send import MultiSendPage
            self.master.open_page(MultiSendPage(self.master))

        multi_send_page_button = ttk.Button(foot, text='群发消息', command=open_multi_send_page)
        multi_send_page_button.place(**scale(relx=1, x=-100, y=0, width=80, height=30))

        def open_multi_send_file_page():
            from interface.pages.multi_send_file import MultiSendFilePage
            self.master.open_page(MultiSendFilePage(self.master))

        multi_send_page_button = ttk.Button(foot, text='发送文件', command=open_multi_send_file_page)
        multi_send_page_button.place(**scale(relx=1, x=-200, y=0, width=80, height=30))

        self.update_user_label()

        self.start_users_update_background_thread()

    def switch_chat_page(self, account):
        self.chat_page_port.close_page()
        self.chat_page_port.open_page(ChatPage(self.chat_page_port, account))

    def add_user(self, user):
        user_button = ttk.Button(self.user_list.inner.tkw, text='{}\n{}'.format(user['account'], user['username']),
                                 command=lambda: self.switch_chat_page(user['account']))
        user_button.place(**scale(relx=0, y=80 * self.user_count, relwidth=1, height=80))
        self.user_list.update()
        self.user_count += 1

    def update_users(self):
        for user in memory.users.values():
            if user['account'] not in self.displayed_users:
                self.add_user(user)
                self.displayed_users.append(user['account'])

    def update_user_label(self):
        try:
            res = request('/user/update', {})
            self.user_label['text'] = '{} ({})'.format(res['username'], res['account'])
        except Exception as e:
            traceback.print_exception(e)

    def start_receive_agent(self):
        self.receive_agent = ReceiveAgent()
        self.receive_agent.start()

    def start_users_update_background_thread(self):
        def run():
            while self.thread_continue:
                self.update_users()
                time.sleep(0.5)
        threading.Thread(target=run, daemon=True).start()

    def destroy(self):
        Page.destroy(self)
        self.thread_continue = False
        self.receive_agent.stop()
